﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Drawing.Text;
using Aras.IOM;
using System.Xml;

namespace WindowsFormsApplication1
{
  public partial class Main : Form
  {
    [System.Runtime.InteropServices.DllImport("gdi32.dll")]
    private static extern IntPtr AddFontMemResourceEx(IntPtr pbFont, uint cbFont,
       IntPtr pdv, [System.Runtime.InteropServices.In] ref uint pcFonts);

    private Innovator _inn;
    private HttpServerConnection _conn;
    private PrivateFontCollection _fonts = new PrivateFontCollection();

    public Main()
    {
      InitializeComponent();

      try
      {
        unsafe
        {
          fixed (byte* pFontData = Properties.Resources.Lato_Reg)
          {
            uint dummy = 0;
            _fonts.AddMemoryFont((IntPtr)pFontData, Properties.Resources.Lato_Reg.Length);
            AddFontMemResourceEx((IntPtr)pFontData, (uint)Properties.Resources.Lato_Reg.Length, IntPtr.Zero, ref dummy);
          }
        }
      }
      catch
      {
        MessageBox.Show("Font does not correctly appear");
      }

      this.Font = new Font(_fonts.Families[0], 12);
      browser.ObjectForScripting = new BrowserInterop(this);
      browser.Navigate("file:///" + Application.StartupPath.Replace('\\','/') + "/loading.htm");
      table.Visible = false;

      url.Text = Properties.Settings.Default.Url;
      userName.Text = Properties.Settings.Default.UserName;
      url_Validated(url, new EventArgs());
    }

    private void browser_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e)
    {
      table.Visible = true;
    }

    private static string _lastUrl = null;
    private void url_Validated(object sender, EventArgs e)
    {
      this.UseWaitCursor = true;
      try
      {
        if (!string.IsNullOrEmpty(url.Text) && url.Text != _lastUrl)
        {
          databases.Items.Clear();
          _conn = IomFactory.CreateHttpServerConnection(url.Text);
          string[] dbs = _conn.GetDatabases();
          for (int i = 0; i < dbs.Length; i++)
          {
            databases.Items.Add(dbs[i]);
          }
          if (dbs.Length > 0)
          {
            if (_lastUrl == null)
            {
              databases.SelectedItem = Properties.Settings.Default.Database;
            }
            else
            {
              databases.SelectedItem = dbs[0];
            }
          } 
          _lastUrl = url.Text;
        }
      }
      catch (Exception err)
      {
        MessageBox.Show(err.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Warning);
      }
      finally
      {
        this.UseWaitCursor = false;
      }
    }

    private void login_Click(object sender, EventArgs e)
    {
      this.UseWaitCursor = true;
      try
      {
        _conn = IomFactory.CreateHttpServerConnection(url.Text, databases.SelectedItem.ToString(), userName.Text, password.Text);
        Item login_result = _conn.Login();

        if (login_result.isError())
        {
          //get details of error
          string error_str = login_result.getErrorString();

          //Interpret message string  - remove header text before : symbol
          int pos = error_str.IndexOf(':') + 1;
          if (pos > 0)
          {
            error_str = error_str.Substring(pos);
          }
          //If error contains keyword clean up message text
          if (error_str.Contains("Authentication"))
          {
            error_str = "Invalid user or password";
          }

          if (error_str.Contains("Database"))
          {
            error_str = "Database not available";
          }

          DisplayMessage("<h1>Login failed!</h1><p>" + error_str + "</p>");
          return;
        }

        Properties.Settings.Default.Url = url.Text;
        Properties.Settings.Default.UserName = userName.Text;
        Properties.Settings.Default.Database = databases.SelectedItem.ToString();
        Properties.Settings.Default.Save();

        //Get innovator object
        _inn = IomFactory.CreateInnovator(_conn);
        browser.Navigate("file:///" + Application.StartupPath.Replace('\\', '/') + "/index.htm");
        table.Visible = false;
      }
      finally
      {
        this.UseWaitCursor = false;
      }
    }

    private void DisplayMessage(string msg)
    {
      browser.Document.InvokeScript("setHtml", new object[] { msg });
    }

    [System.Runtime.InteropServices.ComVisibleAttribute(true)]
    public class BrowserInterop
    {
      private Main _parent;

      public BrowserInterop(Main parent)
      {
        _parent = parent;
      }

      public string getUserID()
      {
        return _parent._conn.GetUserId();
      }
      public string GetDatabaseName()
      {
        return _parent._conn.GetDatabaseName();
      }
      public string CallAction(string action, string query)
      {
        var param = new XmlDocument();
        var result = new XmlDocument();
        param.LoadXml(query);
        _parent._conn.CallAction(action, param, result);
        return result.OuterXml;
      }
    }
  }
}
